/**
 * Created by ${PRODUCT_NAME}.
 * User: skylerparr
 * Date: 1/25/11
 * Time: 7:18 PM
 * To change this template use File | Settings | File Templates.
 */
package com.thoughtorigin.meta {
import com.thoughtorigin.flux.Flux;
import com.thoughtorigin.module.ModuleLoader;
import com.thoughtorigin.reflect.Describe;
import com.thoughtorigin.reflect.MetaReader;
import com.thoughtorigin.util.Instantiator;

import flash.utils.getQualifiedClassName;

public class MetaReaderWorker implements MetaOperator {

    private var _metaReader: MetaReader;
    private var _moduleLoader: ModuleLoader;
    private var _instantiator: Instantiator;
    private var _flux: Flux;

    public function MetaReaderWorker() {
    }

    public function inject(clazz:Class, args:Array, callback:Function):void {
        var retVal: Object = _instantiator.create(clazz, args);
        operateMetaData(clazz, retVal, callback);
    }

    public function injectObject(object:Object, callback:Function = null):void {
        var clazz: Class = _moduleLoader.getClassByName(getQualifiedClassName(object));
        operateMetaData(clazz, object, callback)
    }

    public function operateMetaData(clazz:Class, returnObject:Object, callback:Function):void {
        _metaReader.populateMetaData(Describe.type(clazz), function(): void {
            //todo: find a solution to this circle dependency to the FunctionMetaWorker
            var _metaDataWorker: MetadataWorker = MetadataWorker(_flux.getProperty("metadataWorker"));
            _metaDataWorker.operate(returnObject, _metaReader.classMetaData, function(): void {
                if(callback != null) {
                    callback.call(this, returnObject);
                }
            });
        });
    }

    [Inject]
    public function set metaReader(value: MetaReader): void {
        _metaReader = value;
    }

    [Inject]
    public function set moduleLoader(value: ModuleLoader): void {
        _moduleLoader = value;
    }

    [Inject]
    public function set flux(value:Flux):void {
        _flux = value;
    }

    [Inject]
    public function set instantiator(value:Instantiator):void {
        _instantiator = value;
    }
}
}
